#!/bin/sh
#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#/* Copyright 2002-2003 by Mark Wolgemuth, All rights reserved.             */
#/* Copyright 2002-2003 by Employease, Inc.  All rights reserved.           */
#/*                                                                         */
#/* Redistribution and use in source and binary forms, with or without      */
#/* modification, are permitted provided that the following conditions      */
#/* are met:                                                                */
#/*                                                                         */
#/*    1. Redistributions of source code must retain the above copyright    */
#/* notice, this list of conditions and the following disclaimer.           */
#/*    2. Redistributions in binary form must reproduce the above copyright */
#/* notice, this list of conditions and the following disclaimer in the     */
#/* documentation and/or other materials provided with the distribution.    */
#/*                                                                         */
#/* THIS SOFTWARE IS PROVIDED BY THE MOD_ATHENA PROJECT ``AS IS'' AND ANY   */
#/* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE       */
#/* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR      */
#/* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR        */
#/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,   */
#/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,     */
#/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR      */
#/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     */
#/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT            */
#/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
#/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
#/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

ATH_AGENT_SH_VERSION="ath_monitor.sh 0.1 2003/03/26 (C) mark wolgemuth"

## search down to "main begin" for logic flow
##

## internal vars
if [ "${ATH_ETC_DIR}" = "" ]
then
    ATH_ETC_DIR="."
fi
. ${ATH_ETC_DIR}/ath_shell_cmds.sh

ATH_PID_FILE=/tmp/ath_mirror_sh.pid
GET_CMD=""
AGENT_OPTS=""
HOST_TYPE=`uname`
ATH_OPT_VERBOSE=""
ATH_OPT_QUIET=""
ATH_OPT_BG="NO"
ATH_OPT_LOG=""
ATH_OPT_BURL=""
ATH_OPT_FREQ=""
ATH_OPT_HOST=""
ATH_OPT_LOGFILE=""
ATH_OPT_MIRROR=""
ATH_OPT_MIRR_PER_REQ=3

ATH_GET_ALL_PHYS="/status/phys/?h=*,f=%s"
ATH_GET_ALL_FARM="/status/farm/?n=*,f=%s"

# globs #
GET_CMD_PHYS=""
GET_CMD_FARM=""
GET_CMD_MIRR=""
ATH_PHYS_STATE=""
ATH_FARM_STATE=""
ATH_MIRR_TODO=""

# usage() prints usage
usage() {
    echo "ath_agent.sh [-v] [-q] [-b] [-?] [-u BASEURL] [-f frequency]"
    echo "             [-h hostname] [-s send_update_string]"
    echo ""
    echo "  -v       Prints version and exits"
    echo "  -q       Suppresses all status and warning messages (quiet)"
    echo "  -b       Runs in background"
    echo "  -u (url) Specifies base URL to reach mirror source"
    echo "  -m (url) Specifies base URL to reach mirror target"
    echo "  -f (sec) Sets update frequency (default to 5)"
    echo "  -o (log) Sets file to log to"
    echo "  -k       Kill the currently running daemon and exit"
    return 0
}

# set_opts() runs getopts and sets defaults
set_opts() {
    while getopts "vVqblu:f:m:k" OPTTYPE; do
	case ${OPTTYPE} in
	"v")
	    echo "${ATH_AGENT_SH_VERSION}"
	    exit
	    ;;
	"V") 
	    ATH_OPT_VERBOSE="1"
	    ;;
	"q")
	    ATH_OPT_QUIET="1"
	    ;;
	"b")
	    ATH_OPT_BG="YES"
	    ;;
	"l")
	    ATH_OPT_LOG="1"
	    ;;
	"u")
	    ATH_OPT_BURL="${OPTARG}"
	    ;;
	"f")
	    ATH_OPT_FREQ="${OPTARG}"
	    ;;
	"o")
	    ATH_OPT_LOGFILE="${OPTARG}"
	    touch ${ATH_OPT_LOGFILE} > /dev/null 2>&1
	    if !(test -e ${ATH_OPT_LOGFILE}); then
		echo "Cannot create log file: ${ATH_OPT_LOGFILE}"
	    fi
	    ;;
	"m")
	    ATH_OPT_MIRROR="${OPTARG}"
	    ;;	    
	"k")
	    loop_kill
	    exit
	    ;;
	[?])
	    usage
	    exit
	    ;;
	esac
    done
    # do defaults
    if [ "${ATH_OPT_BURL}" = "" ]; then
	status_msg "WARNING: using default base athena engine URL"
	ATH_OPT_BURL="http://localhost:8080/ath"
    fi
    if [ "${ATH_OPT_HOST}" = "" ]; then
	ATH_OPT_HOST=`hostname`
    fi
    if [ "${ATH_OPT_FREQ}" = "" ]; then
	ATH_OPT_FREQ="5"
    fi
    if [ "${ATH_OPT_MIRR_PER_REQ}" -gt 3 ] ; then
	status_msg "WARNING: setting mirror sub reqs per req > 3 is dangerous"
    fi
}

mirror_in_pieces() {
    ATH_MIRR_DO=""
    while ( [ "$#" -gt "$ATH_OPT_MIRR_PER_REQ" ] )
    do
	COUNT="0"
	ATH_MIRR_DO=""
	while ( [ "$COUNT" -lt "$ATH_OPT_MIRR_PER_REQ" ] )
	do
	    if [ "$ATH_MIRR_DO" = "" ]
	    then
		ATH_MIRR_DO="${1}"
	    else
		ATH_MIRR_DO="${1}&${ATH_MIRR_DO}"
	    fi
	    shift 1
	    COUNT=`expr $COUNT + 1`
	done
	if [ "$ATH_OPT_VERBOSE" = "1" ]
	then
	    status_msg "GET_CMD_MIRR: $GET_CMD_MIRR"
	fi
	GET_CMD_MIRR="${AGENT_DIR}/${AGENT_BIN} ${AGENT_OPTS} \
	    ${ATH_OPT_MIRROR}${ATH_MIRR_DO}"
	GET_CMD_RESULT=`${GET_CMD_MIRR}`
    done

    ATH_MIRR_DO=""
    for JOB in $@
    do
	    if [ "$ATH_MIRR_DO" = "" ]
	    then
		ATH_MIRR_DO="${1}"
	    else
		ATH_MIRR_DO="${1}&${ATH_MIRR_DO}"
	    fi
    done
    GET_CMD_MIRR="${AGENT_DIR}/${AGENT_BIN} ${AGENT_OPTS} \
	${ATH_OPT_MIRROR}${ATH_MIRR_DO}"
    GET_CMD_RESULT=`${GET_CMD_MIRR}`
}

loop_run() {
    ATH_MIRR_TODO=""
    status_msg "Mirroring ${ATH_OPT_BURL} to ${ATH_OPT_MIRROR}"

    GET_CMD_PHYS="${AGENT_DIR}/${AGENT_BIN} ${AGENT_OPTS} \
	${ATH_OPT_BURL}${ATH_GET_ALL_PHYS}"
    ATH_PHYS_STATE=`$GET_CMD_PHYS`
    CHK_ERR=`chk_ath_return $ATH_PHYS_STATE`

    if [ "$CHK_ERR" = "PASS" ]
    then
	for STATE in $ATH_PHYS_STATE
	do
	    ATH_MIRR_TODO="/mirror/phys/?${STATE} ${ATH_MIRR_TODO}"
	done
    else
	status_msg "Error returned by mod_athena: $ATH_PHYS_STATE"
    fi

    GET_CMD_FARM="${AGENT_DIR}/${AGENT_BIN} ${AGENT_OPTS} \
	${ATH_OPT_BURL}${ATH_GET_ALL_FARM}"
    ATH_FARM_STATE=`$GET_CMD_FARM`
    CHK_ERR=`chk_ath_return $ATH_FARM_STATE`

    if [ "$CHK_ERR" = "PASS" ]
    then
	for STATE in $ATH_FARM_STATE
	do
	    ATH_MIRR_TODO="/mirror/farm/?${STATE} ${ATH_MIRR_TODO}"
	done
    else
	status_msg "Error returned by mod_athena: $ATH_FARM_STATE"
    fi
    
    mirror_in_pieces $ATH_MIRR_TODO
}

## main begin ##
################

setup
set_opts $@
chk_agent_bin
add_agent_opts

exec_handler
